package com.nw.service.serviceImpl;

import com.alibaba.fastjson.JSONObject;
import com.nw.common.Result;
import com.nw.enums.ReturnStatusEnum;
import com.nw.enums.TableName;
import com.nw.enums.ValidateReturnCodeEnum;
import com.nw.plungin.MongoManager;
import com.nw.redis.RedisConfig;
import com.nw.redis.RedisService;
import com.nw.service.MongoService;
import com.nw.utils.MD5Util;
import com.nw.utils.StringUtil;
import com.nw.utils.UUIDUtil;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Transactional
@Service
public class MongoServiceImpl implements MongoService{
    @Autowired
	private MongoTemplate mongoTemplate;
    @Autowired
	private RedisService redisService;

    @Autowired
    RedisConfig redisConfig;

    @Override
    public long queryCount(String collectionName, Map<String, Object> query) {
        return MongoManager.queryCount(collectionName,query,mongoTemplate);
    }

    @Override
    public void add(String collectionName, Map<String, Object> map) {
        MongoManager.add(collectionName,map,mongoTemplate);
    }

    @Override
    public void addBatch(String collectionName, List<Map<String, Object>> list) {
        MongoManager.addBatch(collectionName,list,mongoTemplate);
    }

    @Override
    public void update(String collectionName, Map<String, Object> query, Map<String, Object> map) {
        MongoManager.update(collectionName,query,map,mongoTemplate);
    }

    @Override
    public void delete(String collectionName, Map<String, Object> query) {
          MongoManager.delete(collectionName,query,mongoTemplate);
    }

    @Override
    public List<Document> query(String collectionName, Map<String, Object> query, Map<String, Object> sort, int skip, int limit) {

        return MongoManager.query(collectionName,query,sort,skip,limit,mongoTemplate);
    }

    @Override
    public Document queryOne(String collectionName, Map<String, Object> query) {
        return  MongoManager.queryOne(collectionName,query,mongoTemplate);
    }

    @Override
    public List<Document> queryFields(String collectionName, Map<String, Object> query, Map<String, Object> sort, int skip, int limit) {
        return MongoManager.queryFields(collectionName,query,sort,skip,limit,mongoTemplate);
    }

    @Override
    public boolean  validateToken(Object token) {
        if(token == null){
            return false;
        }
        Map<String, Object> query = new HashMap<>();
        query.put("token",token);
        Document validate = this.queryOne(TableName.TEST_VALIDATE,query);
        if(validate.isEmpty()){
            return false;
        }
        return true;
    }

    @Override
    public boolean validateUserNameForRepeat(String user_name) {
        Map<String, Object> queryForUser = new HashMap<>();
        queryForUser.put("user_name",user_name);
        Document user = this.queryOne(TableName.TEST_USER,queryForUser);
        if(user!=null && !user.isEmpty()){
            return false;
        }
        return true;
    }

    @Override
    public Result validateParam(JSONObject map) {
        Result result = new Result();
        Object token = map.get("token");
        if(!this.validateToken(token)){
            result.setStatus(ReturnStatusEnum.FAILURE.getCode());
            result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_FAILURE.getCode());
            result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_FAILURE.getDesc());
            return result;
        }else{
            Map<String, Object> queryForUser = new HashMap<>();
            queryForUser.put("token",token);
            Document user = this.queryOne(TableName.TEST_USER,queryForUser);
            if(!user.isEmpty()){
                result.setData(user);
            }else{
                result.setStatus(ReturnStatusEnum.FAILURE.getCode());
                result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
                result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_UNEXIT_FAILURE.getCode());
                result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_UNEXIT_FAILURE.getDesc());
                return result;
            }
        }
        result.setStatus(ReturnStatusEnum.SUCCESS.getCode());
        result.setMsg(ReturnStatusEnum.SUCCESS.getDesc());
        result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_SUCESS.getCode());
        result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_SUCESS.getDesc());

        return result;
    }

    @Override
    public Result login(JSONObject map) {
        Result result = new Result();
        Map<String, Object> queryForUser = new HashMap<>();
        String user_name = map.get("user_name").toString();
        String pass_word = map.get("pass_word").toString();
        /*MD5加密*/
        String pass = MD5Util.getMD5(pass_word);

        queryForUser.put("user_name",user_name);
        Document user = this.queryOne(TableName.TEST_USER,queryForUser);
        if(!user.isEmpty()){
            queryForUser.put("pass_word",pass);
            Document userForPass = this.queryOne(TableName.TEST_USER,queryForUser);
            if(!userForPass.isEmpty()){
                /*生成token存入验证表信息*/
                Map<String, Object> valid = new HashMap<>();
                String token = UUIDUtil.uuid();
                valid.put("token",token);
                this.add(TableName.TEST_VALIDATE,valid);//存入权限,当日志用
                redisService.getInstance().setex(token, redisConfig.getSecond(),userForPass.toString());//存入redis
                userForPass.put("token",token);
               /* user.put("token",token);
                this.update(TableName.TEST_USER,userForPass,user);//更新用户表*/
                result.setStatus(ReturnStatusEnum.SUCCESS.getCode());
                result.setMsg(ReturnStatusEnum.SUCCESS.getDesc());
                result.setReturnMsg(ValidateReturnCodeEnum.USER_LOGIN_SUCCESS.getDesc());
                result.setReturnMsg(ValidateReturnCodeEnum.USER_LOGIN_SUCCESS.getDesc());
                result.setData(userForPass);
            }else{
                result.setStatus(ReturnStatusEnum.FAILURE.getCode());
                result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
                result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_USERNAME_EXIT_FAILURE.getCode());
                result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_USERNAME_EXIT_FAILURE.getDesc());
            }
        }else{
            result.setStatus(ReturnStatusEnum.FAILURE.getCode());
            result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_PASS_FAULCE.getCode());
            result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_PASS_FAULCE.getDesc());
        }
        return result;
    }

    @Override
    public long loginOut(String token ) {
        long count = redisService.getInstance().del(token);
        return count;
    }


    @Override
    public Result update(JSONObject map) {
        Result result = new Result();
       /*token登陆验证*/
        if(!this.validateToken(map.get("token"))){
            result.setStatus(ReturnStatusEnum.FAILURE.getCode());
            result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_FAILURE.getCode());
            result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_LOGIN_FAILURE.getDesc());
            return  result;
        }
        if(StringUtil.isEmpty(map.get("_id"))){
            result.setStatus(ReturnStatusEnum.FAILURE.getCode());
            result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_ID_EXIT_FAILURE.getCode());
            result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_ID_EXIT_FAILURE.getDesc());
            return result;
        }
        Map<String,Object> queryUser = new HashMap<>();
        queryUser.put("_id",map.get("_id"));
        Document find_user =  this.queryOne(TableName.TEST_USER,queryUser);
        if(find_user == null){
            result.setStatus(ReturnStatusEnum.FAILURE.getCode());
            result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_EXIT_FAILURE.getCode());
            result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_EXIT_FAILURE.getDesc());
            return result;
        }
        Object user_name = map.get("user_name");
        if(user_name != null){
            if( !find_user.get("user_name").equals(user_name)  && !this.validateUserNameForRepeat(user_name.toString())){
                result.setStatus(ReturnStatusEnum.FAILURE.getCode());
                result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
                result.setReturnCode(ValidateReturnCodeEnum.USER_VALIDATE_EXIT_FAILURE.getCode());
                result.setReturnMsg(ValidateReturnCodeEnum.USER_VALIDATE_EXIT_FAILURE.getDesc());
                return result;
            }
        }
        if(!StringUtil.isEmpty(map.get("pass_word"))){
            String pass_word = map.get("pass_word").toString();
            String pass = MD5Util.getMD5(pass_word);
            map.put("pass_word",pass);
        }
        this.update(TableName.TEST_USER,find_user,map);
        find_user =  this.queryOne(TableName.TEST_USER,queryUser);//重新查询放入redis
        redisService.getInstance().setex(map.get("token").toString(), redisConfig.getSecond(),find_user.toString());//存入redis
        result.setStatus(ReturnStatusEnum.SUCCESS.getCode());
        result.setMsg(ReturnStatusEnum.SUCCESS.getDesc());
        result.setReturnCode(ValidateReturnCodeEnum.USER_UPDATE_SUCCESS.getCode());
        result.setReturnMsg(ValidateReturnCodeEnum.USER_UPDATE_SUCCESS.getDesc());
        return  result;
    }
}
